package com.lry.crawlers.video.processor;

import com.alibaba.fastjson.JSONObject;
import com.jnewbie.JProcessor;
import com.jnewbie.request.JPage;
import com.lry.crawlers.video.entity.VideoChapter;
import com.lry.crawlers.video.entity.VideoVariable;
import com.lry.crawlers.video.pipeline.VideoPipeline;
import com.lry.crawlers.video.service.VideoChapterService;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class VideoPlusUpJProcessor extends JProcessor {
    public volatile static int allUrl = 0;
    public Map<String,Object> map;
    private VideoPipeline videoPipeline;
    private VideoChapterService videoChapterService;
    private VideoVariable videoVariable;
    public String infId;

    public VideoPlusUpJProcessor() {
    }


    public VideoPlusUpJProcessor(String infId, Map<String,Object> map, VideoPipeline videoPipeline, VideoChapterService videoChapterService, VideoVariable videoVariable) {
        this.infId = infId;
        this.map = map;
        this. videoPipeline = videoPipeline;
        this.videoChapterService = videoChapterService;
        this.videoVariable = videoVariable;
    }



    @Override
    public JPage process(JPage jPage) {
        
        if(jPage.getUrl().contains("www.baidu.com")){
            jPage.addGoUrls(new ArrayList<>(map.keySet()));
            return jPage;
        }
        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
        LinkedHashMap<String, String> hmapz = JSONObject.parseObject(JSONObject.toJSONString(videoVariable), LinkedHashMap.class);
        Field[] declaredFields = videoVariable.getClass().getDeclaredFields();
        LinkedHashMap<String, String> hmap = new LinkedHashMap<>();
        for (Field declaredField : declaredFields) {
            hmap.put(declaredField.getName(), hmapz.get(declaredField.getName()));
        }
        hmap.remove("mode");
        int chapterSort = Integer.parseInt(String.valueOf(hmap.remove("chapterSort")));
        hmap.remove("id");
        hmap.remove("deleted");
        hmap.remove("creationTime");
        hmap.remove("searchUrl");
        hmap.remove("name");
        hmap.remove("encoding");
        hmap.remove("url");
        hmap.remove("protocol");
        for (String s : hmap.keySet()) {
            try{
                String key = hmap.get(s);
                if (key != null && key.contains("${url}"))
                    key =  key.replace("${url}", jPage.getUrl());
                //判断是否包含固定值
                if (key != null && key.length() > 0) {
                    if (!key.contains("-@") && !key.contains("@-")) {
                        //xpath与正则提取出来
                        String[] x_z = key.split("-!-");
                        //获取xpath与正则匹配的值
                        List<String> result = null;
                        try {
                            result = !x_z[0].equals("") ? jPage.xpath(x_z[0]).regex(x_z.length != 1 ? x_z[1] : "(.*)").trim().getAll() :
                                    x_z.length > 1 && !x_z[1].equals("") ? jPage.regex(x_z[1]).trim().getAll() : null;
                        } catch (Exception e) {

                        }
                        //如果获取的值不为空，那就存放
                        if (result != null && result.size() != 0) {
                            map.put(s, result);
                        }
                    } else {
                        //把非固定的值提取出来
                        Pattern pattern = Pattern.compile("-@(.*?)@-", Pattern.DOTALL | Pattern.MULTILINE);
                        Matcher matcher = pattern.matcher(key);
                        List<String> result = null;
                        while (matcher.find()) {
                            //xpath与正则提取出来
                            String[] x_z = matcher.group(1).split("-!-");
                            //获取xpath与正则匹配的值
                            List<String> res = null;
                            try {
                                res = !x_z[0].equals("") ? jPage.xpath(x_z[0]).regex(x_z.length != 1 ? x_z[1] : "(.*)").trim().getAll() :
                                        x_z.length > 1 && !x_z[1].equals("") ? jPage.regex(x_z[1]).trim().getAll() : null;
                            } catch (Exception e) {
                                e
                                        .printStackTrace();
                            }

                            //判断值是否存在
                            if (res != null && res.size() != 0) {
                                //第一次就新增
                                if (result == null) {
                                    result = new ArrayList<>();
                                    for (String re : res) {
                                        result.add(key.replaceFirst("-@(.*?)@-", re));
                                    }
                                    //不是第一次就修改
                                } else {
                                    int j = 0;
                                    String bak = null;
                                    for (String re : res) {
                                        try {
                                            bak = result.get(j);
                                            result.set(j, result.get(j).replaceFirst("-@(.*?)@-", re));
                                        }catch (IndexOutOfBoundsException e){
                                            result.add(j, bak.replaceFirst("-@(.*?)@-", re));
                                        }
                                        j++;
                                    }
                                }
                            }
                        }
                        //判断是否为空，不为空，就存入值，并去除未匹配的-@.*?@-
                        if (result != null && result.size() != 0) {
                            if(result.toString().contains("-@") &&result.toString().contains("@-")) {
                                for (int i = 0; i < result.size(); i++) {
                                    String bak = result.get(i);
                                    if (bak.contains("-@") && bak.contains("@-"))
                                        result.set(i, bak.replaceFirst("-@(.*?)@-", ""));
                                }
                            }
                            map.put(s, result);
                        }
                    }
                }
                //判断是值否为空，不为空，就开始处理
                if (map.get(s) != null) {
                    List<String> tag = (List<String>) map.get(s);
                    switch (s) {
                        case "title":
                            HashMap<String, Object> omap = new HashMap<>();
                            String updateUrl = jPage.getUrl();
                            omap.put("title", ((List<String>) map.get("title")).get(0));
                            try{
                                omap.put("descs", ((List<String>) map.get("descs")).get(0));
                            }catch (Exception e){omap.put("descs","");}
                            try {
                                omap.put("director", ((List<String>) map.get("director")).get(0));
                            }catch (Exception e){omap.put("director","");}
                            try {
                                omap.put("actor", ((List<String>) map.get("actor")).get(0));
                            }catch (Exception e){omap.put("actor","");}
                            try {
                                omap.put("region", ((List<String>) map.get("region")).get(0));
                            }catch (Exception e){omap.put("region","");}
                            try {
                                omap.put("releaseTime", ((List<String>) map.get("releaseTime")).get(0));
                            }catch (Exception e){omap.put("releaseTime","");}
                            try {
                                String rex = "^[1-9]\\d*(\\.\\d+)?$";
                                Pattern p = Pattern.compile(rex);
                                Matcher m = p.matcher(((List<String>) map.get("updateTime")).get(0));
                                if(m.find()){
                                    Date date = new Date(Long.parseLong(((List<String>) map.get("updateTime")).get(0))*1000);
                                    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
                                    String dateString = formatter.format(date);
                                    omap.put("updateTime", dateString);
                                }else{
                                    omap.put("updateTime", ((List<String>) map.get("updateTime")).get(0));
                                }                            }catch (Exception e){omap.put("updateTime",new Date());}
                            try {
                                omap.put("videoType", ((List<String>) map.get("videoType")).get(0));
                            }catch (Exception e){omap.put("videoType","");}
                            try {
                                omap.put("cover", ((List<String>) map.get("cover")).get(0));
                            }catch (Exception e){omap.put("cover","");}
                            omap.put("updateUrl", updateUrl);
                            jPage.addTag(UUID.nameUUIDFromBytes((jPage.getUrl()+"details").getBytes()).toString(),omap);
                            break;

                        case "chapterUrl":
                            //判断是否还要下一页，还要就把数据放到，以下一页URL为key的map中
                            String videoId = (String)this.map.get(jPage.getUrl());
                            List<String> chapterUrls = tag;
                            List<String> chapterTitles = (List<String>)map.get("chapterTitle");
                            Map<String, Object> details =  (Map<String, Object>) jPage.delTag(UUID.nameUUIDFromBytes((jPage.getUrl()+"details").getBytes()).toString());
                            //获取现在的章节数量
                            int xsize = chapterUrls.size();
                            //生成需更新的章节对应排序
                            List<Integer> sortt = new ArrayList();
                            for(int i=0;i<chapterTitles.size();i++){
                                sortt.add(i);
                            }
                            List<VideoChapter> videoChapters = videoChapterService.selectByVideoId(videoId);
                            List<Integer> duplicates= videoChapterService.removeDuplicates(chapterTitles,videoChapters);
                            ArrayList<String> chapterId = new ArrayList<>();
                            for (String chapteru : chapterUrls) {
                                chapterId.add(UUID.nameUUIDFromBytes(chapteru.getBytes()).toString());
                            }
                            if(chapterSort ==1){
                                Collections.reverse(chapterUrls);
                                Collections.reverse(chapterTitles);
                                Collections.reverse(chapterId);
                            }
                            for (int i : duplicates) {
                                chapterUrls.set(i,null);
                                chapterTitles.set(i,null);
                                sortt.set(i,null);
                                chapterId.set(i,null);
                            }
                            while (chapterUrls.remove(null));
                            while (chapterTitles.remove(null));
                            while (sortt.remove(null));
                            while (chapterId.remove(null));

                            if(chapterUrls.size()!=0) {
                                details.put("key", "chapter");
                                details.put("chapterTitle", chapterTitles);
                                details.put("chapterUrl", chapterUrls);
                                details.put("chapterNum", xsize);
                                details.put("videoId", videoId);
                                details.put("chapterId", chapterId);
                                details.put("sortt", sortt);
                                details.put("id", videoVariable.getId());
                                details.put("infId", infId + "!!!" + chapterUrls.size());
                                videoPipeline.process(details);
                            }
                            break;
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return jPage;
    }

}
